package com.ct.config.mybatisPlus;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.log.StaticLog;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.DynamicTableNameInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Map;

@Configuration
@MapperScan(basePackages = {"com.ct.mapper.kk_ycz", "com.ct.mapper.kkrot"})
public class MybatisPlusConfiguration {

    @Value("${spring.datasource.dynamicTables:null}")
    public String dynamicTables;

    /**
     * 添加分页插件
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // 1. 阻止全表更新与删除，防止误操作导致数据丢失
        BlockAttackInnerInterceptor blockAttackInnerInterceptor = new BlockAttackInnerInterceptor();

        // 2. 设置动态表名拦截器，支持根据请求参数动态修改表名
        DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new DynamicTableNameInnerInterceptor();
        dynamicTableNameInnerInterceptor.setTableNameHandler((sql, tableName) -> {
            // 确保表名非空，并且当前表名存在于 dtables 配置列表中
            if (StrUtil.isNotBlank(tableName) && StrUtil.containsIgnoreCase(dynamicTables, tableName)) {
                // 获取当前请求的参数数据
                Map<String, Object> requestData = RequestDataHelper.getRequestData();
                // 如果请求参数为空，则直接返回原始表名
                if (CollUtil.isEmpty(requestData)) {
                    return tableName;
                }
                // 根据请求参数获取动态表名后缀
                String tableNameValues = MapUtil.getStr(requestData, tableName);
                // 记录动态表名信息，方便调试和日志追踪
                StaticLog.info("动态表名,sql->{},tableName->{}_{}", sql, tableName, tableNameValues);
                // 返回拼接后的动态表名，例如：order_202403
                return StrUtil.format("{}_{}", tableName, tableNameValues);
            }
            return tableName;
        });

        // 添加动态表名拦截器
        interceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor);
        // 添加防止全表更新或删除的拦截器，保障数据安全
        interceptor.addInnerInterceptor(blockAttackInnerInterceptor);
        // 分页拦截器，确保分页查询在插件链的最后被执行，以避免影响其他拦截器的逻辑    如果有多数据源可以不配具体类型, 否则都建议配上具体的 DbType
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor()); // 如果配置多个插件, 切记分页最后添加
        return interceptor;
    }


    @Bean
    public MyMetaObjectHandler myMetaObjectHandler() {
        return new MyMetaObjectHandler();
    }

}